//
//  RdbSubscribeManager.swift
//  rdb-led-banner
//  处理支付逻辑
//  Created by radiobox3 on 2025/4/17.
//
import StoreKit
import Alamofire

typealias SubscribeCompletion = (_ isSucess: Bool, _ params: [String: Any]?) -> Void



class RdbSubscribeManager: NSObject, SKPaymentTransactionObserver, SKPaymentQueueDelegate,SKRequestDelegate {
    
    static let shared = RdbSubscribeManager()
    
    /// 是否订阅标识
    private(set) var isSubscribed: Bool = false
    
    private var subscribeCompleted: SubscribeCompletion?
    
    /// 沙盒验证地址
    private let receiptUrlSandbox = "https://sandbox.itunes.apple.com/verifyReceipt"

    ///生产环境验证地址
    private let receiptUrlItunes = "https://buy.itunes.apple.com/verifyReceipt"
    
    /// App Store Connect -->用户和访问-->共享密钥
    private let ShareAppleKey = "cd40a5ab1a154cb0a5aa4162cfa614c4"

    private(set) var isTrialPeriod: Bool = true
    
    private var isPurchasing: Bool = false
    
    
    ///弹出订阅页面
    func showSubscribeGuidePage(scene: RdbSubscribeScene, completion: (() -> Void)?){
        let subscribeController = RdbSubscribeController(scene: scene)
        UIViewController.getCurrentTopController()?.present(RdbNavigationController(rootViewController: subscribeController), animated: true)
    }
    
    
    ///开始订阅流程
    func startSubscribeFlow(product type: RdbSubscribePeriodType,atView controller: UIViewController, completion: SubscribeCompletion?) {
        controller.showLoading(.center)
        self.startSubscribe(product: type) { isSucess, params in
            DispatchQueue.main.async {
                controller.hidenLoading()
                if isSucess {
                    completion?(true,params)
                } else {
                    completion?(false, params)
                }
            }
        }
    }
    
    ///开始订阅
    func startSubscribe(product type: RdbSubscribePeriodType, completion: SubscribeCompletion?) {
        self.subscribeCompleted = completion
        self.isPurchasing = true
        RdbSubscribeProductRequest.shared.requestProduct {[weak self] isSucess, params in
            guard let self = self else {return}
            if isSucess, let product = RdbSubscribeProductRequest.shared.products.first(where: { pro in
                pro.productIdentifier == type.rawValue
            }) {
                self.startPayment(product: product)
            } else {
                self.finishedPayment()
            }
        }
    }
    
    ///恢复订阅
    func restoreSubscribe(completion:SubscribeCompletion?) {
        self.subscribeCompleted = completion
        self.isPurchasing = true
        if SKPaymentQueue.default().transactions.contains(where: { transaction in
            transaction.payment.applicationUsername == UIDevice.getUniqueDeviceIdentifier()
        }) {
            RdbSubscribeProductRequest.shared.requestProduct {[weak self] isSucess, params in
                guard let self = self else {return}
                if isSucess {
                    SKPaymentQueue.default().restoreCompletedTransactions(withApplicationUsername: UIDevice.getUniqueDeviceIdentifier())
                } else {
                    self.finishedPayment()
                }
            }
        } else {
            self.finishedPayment()
        }
    }
    
    //开始支付操作
    private func startPayment(product: SKProduct) {
        if SKPaymentQueue.canMakePayments() {
            let payment = SKMutablePayment(product: product)
            payment.quantity = 1
            payment.applicationUsername = UIDevice.getUniqueDeviceIdentifier()
            SKPaymentQueue.default().add(payment)
        } else {
            self.finishedPayment()
        }
    }
    
    //添加支付观察, 去要启动的时候调用
    func addPaymentObserver() {
        if self.inviteCodeExpire() == false {
            self.isSubscribed = true
        } else if self.subcriptExpire() == false {
            self.isSubscribed = true
        }
        SKPaymentQueue.default().add(self)
    }
    
    //移除支付观察
    func removePaymentObserver() {
        SKPaymentQueue.default().remove(self)
    }
}


extension RdbSubscribeManager {
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            let state = transaction.transactionState
            
            print("subscriptoon status: \(state)")
            
            switch state {
            case .restored:
                self.verifyReceipt {
                    self.finishedPayment(transaction.transactionIdentifier)
                }
                queue.finishTransaction(transaction)
                break
            case .purchasing:
                self.isPurchasing = true
                break
            case .purchased: //交易完成
                self.verifyReceipt {[weak self] in
                    guard let self = self else {
                        return
                    }
                    self.finishedPayment(transaction.transactionIdentifier)
                }
                queue.finishTransaction(transaction)
                break
            case .failed: //交易失败
                queue.finishTransaction(transaction)
                var error: NSError?
                if let userInfo = (transaction.error as? NSError)?.userInfo {
                    error = userInfo["NSUnderlyingError"] as? NSError
                    if error?.code == 3532 {
                        self.isSubscribed = true
                        if self.isPurchasing {
                            NotificationCenter.default.post(name: .rdbSubscribeChange, object: nil)
                        }
                    }
                }
                self.finishedPayment(transaction.transactionIdentifier, errorCode: error?.code)
                break
            default:
                break
            }
        }
    }
    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        print("恢复购买完成")
        
    }
    func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        print("恢复购买失败")
    }
    func finishedPayment(_ transactionId: String? = nil, errorCode: Int? = nil) {
        if self.isPurchasing {
            self.subscribeCompleted?(self.isSubscribed, ["transactionId": transactionId ?? "", "errorCode": errorCode ?? ""])
        }
        self.isPurchasing = false
    }
}

extension RdbSubscribeManager{
    /// 验证账单
    func verifyReceipt(_ isSanbox: Bool = false, _ completed: (() -> Void)? = nil) {
    
        if self.inviteCodeExpire() == false {
            self.isSubscribed = true
            completed?()
            return
        }
        
        guard let receiptString = RdbSubscribeReceiptRequest.shared.getReceiptBase64String() else {
            completed?()
            return
        }
       
        /// 向苹果服务器验证账单
        let purchaseURL = URL(string: isSanbox ? receiptUrlSandbox : receiptUrlItunes)!
        var request = URLRequest(url: purchaseURL)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let jsonBody: [String: Any] = [
                        "receipt-data": receiptString,
                        "password": ShareAppleKey, // App 专用共享密钥
                        "exclude-old-transactions": true
        ]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: jsonBody, options: [])
            
            request.httpBody = jsonData

            let session = URLSession.shared
            let task = session.dataTask(with: request) { (data, response, error) in
                if error != nil {
                    completed?()
                    return
                }
                guard let data = data else {
                    completed?()
                    return
                }
                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                        let status = json["status"] as? Int ?? -1
                        switch status {
                        case 0:
                            print("验证成功")
                            let latestReceipt = json["latest_receipt_info"] as? [[String: String]] ?? []
                            latestReceipt.forEach { infoDic in
                                if let identifier = infoDic["transaction_id"] {
                                    print("\(identifier)")
                                    if let expireDate = infoDic["expires_date_ms"] {
                                        if self.isSubscribed == false {
                                            self.isSubscribed = !self.isExpire(expireDate)
                                            if self.isSubscribed == true {
                                                RdbUserDefaults.update(value: expireDate, keyPath: .rdbSubscribeExpireDate)
                                                NotificationCenter.default.post(name: .rdbSubscribeChange, object: nil)
                                            }
                                        }
                                    }
                                    if self.isTrialPeriod == true {
                                        if let isTrialPeriod = infoDic["is_trial_period"]{
                                            self.isTrialPeriod = isTrialPeriod != "false"
                                            RdbUserDefaults.update(value: isTrialPeriod, keyPath: .rdbTrialPeriod)
                                        }
                                    }
                                }
                            }
                            completed?()
                            break
                        case 21007:
                            print("沙盒环境")
                            self.verifyReceipt(true,completed)
                            break
                        case 21006:
                            self.isSubscribed = false
                            break
                        default:
                            print("验证失败")
                            completed?()
                            break
                        }
                    }
                } catch {
                    print("JSON processing failed: \(error)")
                    completed?()
                }
            }
            task.resume()
        } catch {
            completed?()
        }
    }
    
    
    func isExpire(_ expireDateStr: String) -> Bool {
        // 首先尝试 MS 格式转换
        if let expireTimeInterval = Double(expireDateStr) {
            let expireDate = Date(timeIntervalSince1970: expireTimeInterval / 1000)
            print("expireDate:\(expireDate)")
            let currentDate = Date()
            print("currentDate:\(currentDate)")
            return currentDate > expireDate
        }
        return true
    }
    
    func inviteCodeEffect() {
        self.isSubscribed = true
        RdbUserDefaults.update(value: Date().addingTimeInterval(30 * 24 * 60 * 60), keyPath: .rdbSubscribeExpireDate)
        UserDefaults.standard.synchronize()
        NotificationCenter.default.post(name: .rdbSubscribeChange, object: nil)
    }
    
    func inviteCodeExpire() -> Bool {
        guard let expireDate = RdbUserDefaults.value(for: .rdbSubscribeExpireDate) as? Date else {
            return true
        }
        return Date().compare(expireDate) == .orderedDescending
    }
    
    func subcriptExpire() -> Bool {
        guard let expireDateMs = RdbUserDefaults.stringValue(for: .rdbSubscribeExpireDate) else {
            return true
        }
        return self.isExpire(expireDateMs)
    }
}
